package com.bingxue.edu.migration;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.bingxue.edu.common.enums.CommonStatusEnum;
import com.bingxue.edu.common.enums.EmployeeTypeEnum;
import com.bingxue.edu.common.enums.EnrollStatusEnum;
import com.bingxue.edu.common.enums.GenderEnum;
import com.bingxue.edu.framework.enums.DictEnums;
import com.bingxue.edu.management.education.model.entity.Parent;
import com.bingxue.edu.management.education.model.entity.Student;
import com.bingxue.edu.management.education.service.ParentService;
import com.bingxue.edu.management.education.service.StudentService;
import com.bingxue.edu.management.system.model.entity.Employee;
import com.bingxue.edu.management.system.service.EmployeeService;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

import static com.bingxue.edu.common.constant.AuthConstants.ROOT_ID;

/**
 * @author panbo
 * @since 2024/9/18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StudentMigrationService {

    private static final String MAIN_DS = "main";
    private static final String LEGACY_DS = "legacy";
    private final ParentService parentService;
    private final StudentService studentService;
    private final EmployeeService employeeService;

    //    @Transactional(rollbackFor = Exception.class)
    public void migrationParents() {
        try{
            DataSourceKey.use(LEGACY_DS);
            String sql = "select * from edu_parent where is_deleted = 0";
            List<Row> rows = Db.selectListBySql(sql);
            DataSourceKey.use(MAIN_DS);
            int count = rows.size();
            for (int i = 0; i < count; i++) {
                Row item = rows.get(i);
                Parent parent = new Parent();
                parent.setId(item.getString("id"));
                parent.setName(item.getString("name"));
                parent.setMobilePhone(item.getString("mobile"));
                parent.setUsername(item.getString("mobile"));
                parent.setRecommender(item.getString("recommender"));
                parent.setStatus(CommonStatusEnum.ENABLED);
                // 平均耗时 100ms
                parent.setPassword(DigestUtil.bcrypt(RandomUtil.randomString(8)));
                parent.setCreateUser("0");
                parent.setCreateTime(item.getLocalDateTime("create_time"));
                parent.setUpdateUser("0");
                parentService.save(parent);
                System.out.printf("%d/%d%n", i+1, count);
            }
        } finally {
            DataSourceKey.clear();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void migrationStudents() {
        try{
            DataSourceKey.use(LEGACY_DS);
            String sql = """
                select t1.*, t2.mobile as parent_mobile from edu_student t1 left join edu_parent t2 on t1.parent_id = t2.id where t1.is_deleted = 0
            """;
            List<Row> rows = Db.selectListBySql(sql);

            List<Student> newStudentList = rows.stream().map(item -> {
                Student student = new Student();
                student.setId(item.getString("id"));
                student.setName(item.getString("name"));
                String pinyin = PinyinUtil.getPinyin(student.getName(), "");
                student.setNamePinyin(pinyin);
                student.setEnrollStatus(EnrollStatusEnum.NO_ENROLL);
                student.setParentId(item.getString("parent_id"));
                student.setParentPhone(item.getString("parent_mobile"));
                student.setParentRelation("parent");
                student.setGender(DictEnums.getByValue(item.getInt("gender"), GenderEnum.class));
                student.setBirthdate(item.getString("birthdate") == null ? null : LocalDate.parse(item.getString("birthdate")));
                student.setAdmissionYear(item.getInt("school_year"));
                student.setFulltimeSchool(item.getString("school"));
                student.setCreateUser("0");
                student.setCreateTime(item.getLocalDateTime("create_time"));
                student.setUpdateUser("0");
                return student;
            }).toList();
            DataSourceKey.use(MAIN_DS);
            studentService.saveBatch(newStudentList, 100);
        } finally{
            DataSourceKey.clear();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void migrationTeachers() {
        try{
            DataSourceKey.use(LEGACY_DS);
            String sql = """
                select * from edu_teacher where is_deleted = 0
            """;
            List<Row> rows = Db.selectListBySql(sql);

            List<Employee> newDataList = rows.stream().map(item -> {
                Employee employee = new Employee();
                String mobile = item.getString("mobile");
                String name = item.getString("realname");
                String pinyin = PinyinUtil.getPinyin(name, "");
                employee.setId(item.getString("id"));
                employee.setOrgId(ROOT_ID);
                employee.setType(EmployeeTypeEnum.LEAD_TEACHER);
                employee.setName(name);
                employee.setCode(pinyin);
                employee.setUsername(mobile);
                employee.setPassword(DigestUtil.bcrypt("bx!" + mobile.substring(mobile.length () - 4)));
                employee.setMobilePhone(mobile);
                employee.setGender(DictEnums.getByValue(item.getInt("gender"), GenderEnum.class));
                employee.setBirthdate(item.getString("birthdate") == null ? null : LocalDate.parse(item.getString("birthdate")));
                employee.setStatus(CommonStatusEnum.ENABLED);
                employee.setCreateUser("0");
                employee.setCreateTime(item.getLocalDateTime("create_time"));
                employee.setUpdateUser("0");
                return employee;
            }).toList();
            DataSourceKey.use(MAIN_DS);
            employeeService.saveBatch(newDataList, 10);
        } finally{
            DataSourceKey.clear();
        }
    }
}
